#include "camera.h"


Camera::Camera(const int& index, const CamParam& param, QObject *parent)
    : QObject{parent}, _camera_index(index),_camera_param(param)
{


}

Camera::~Camera()
{
    _camera_timer->stop();
    if (_camera) {
        _camera->release();
        delete _camera;
    }
    qDebug()<<"~Camera"<<_camera_index<<"()";
}

void Camera::Open()
{
    _camera = new cv::VideoCapture(_camera_index);
    if (!_camera->isOpened()) {
        qCritical() << "Camera" << _camera_index << "打开失败";
        delete _camera;
        _camera = nullptr;
        return;
    }
    qInfo() << "Camera" << _camera_index << "打开成功";

    _camera_timer = new QTimer(this);
    connect(_camera_timer, &QTimer::timeout, this, &Camera::Work);
    _camera_timer->start(CAMERA_FPS); // 30Hz 采集率
}



void Camera::Work()
{
    cv::Mat frame;
    *_camera >> frame;
    if (frame.empty()|| frame.data==nullptr) {
        qCritical() << "Camera" << _camera_index << "读取失败";
        return;
    }

    g_rw_mtx.lock();
    bool hot_vision = g_fromplc_data.hot_vision;
    bool cold_vision = g_fromplc_data.cold_vision;
    g_rw_mtx.unlock();

    bool hot_res=false, cold_res=false;
    switch(_camera_index){
        case 0:
            if(hot_vision) {
                H_Mid2_CV_det(frame,_camera_param,hot_res);
            }
            break;
        case 1:
            if(cold_vision) {
                C_Mid1_CV_det(frame,_camera_param,cold_res);
            }
            break;
        case 2:
            break;
        default:
            qCritical()<<"相机索引不正确";
            break;
    }

    g_rw_mtx.lock();
    g_toplc_data.hot_product = hot_res;
    g_toplc_data.cold_product = cold_res;
    g_rw_mtx.unlock();

    //显示
    cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB); // OpenCV 默认 BGR，需要转换为 RGB
    QImage img = QImage((const unsigned char*)frame.data, frame.cols, frame.rows, QImage::Format_RGB888).copy(); //多线程传递需要拷贝数据
    emit show_camera(_camera_index, img);
}

void Camera::UpdateParam(const CamParam &param)
{
    _camera_param = param;
    qDebug()<<"update camera"<<_camera_index;
}


int H_Mid2_CV_det(cv::Mat& frame_data, const CamParam& cam, bool& result_img)
{
    //qDebug()<<"camera0 running...";
    ImageDet  det1;
    /*Mat img = imread("D:/img/cut/cold/1frame_68.jpg",0);
    waitKey(0);*/
    //VideoCapture cap("D:/img/cut/2_cold.mp4");  // 替换成你的视频文件路径

    //double fps = cap.get(CAP_PROP_FPS);
    //if (!cap.isOpened()) {
    //    cerr << "无法打开视频文件！" << endl;
    //    return -1;
    //}
    ////namedWindow("Video", WINDOW_NORMAL);

    ////cv::VideoCapture cap("D:/img/cut/2_cold.mp4");
    ////int total_frames = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_COUNT));
    ////double fps = cap.get(cv::CAP_PROP_FPS);
    //cv::Mat frame;
    //int frame_count = 0;


    //画一个大ROI
    std::vector<Point> pointsA = {
        Point(cam.A[0],cam.A[1]),
        Point(cam.A[2],cam.A[3]),
        Point(cam.A[4],cam.A[5]),
        Point(cam.A[6],cam.A[7])
    };

    //一个小ROI
    std::vector<Point> pointsB = {
        Point(cam.B[0],cam.B[1]),
        Point(cam.B[2],cam.B[3]),
        Point(cam.B[4],cam.B[5]),
        Point(cam.B[6],cam.B[7])
    };


    // 定义裁剪区域
    Rect cropRegion(pointsA[3].x, pointsA[0].y, pointsA[2].x - pointsA[3].x, pointsA[2].y - pointsA[1].y);

    try
    {
        // 逐帧读取视频
        /*  while (true)
        {*/
        // 读取一帧图像
        /*cap >> frame;*/


        /*  string filename = "test.jpg";
              imwrite(filename, frame); */

        /*std::string filename = "D:/image/image_" + getCurrentTimeString() + ".png";
            cv::imwrite(filename, frame);*/
        //cv::Mat frame(480, 640, CV_8UC3, (void*)imageData);
        //Mat frame_clone = frame.clone();
        Mat frame=frame_data.clone();
        cv::cvtColor(frame, frame, cv::COLOR_BGR2GRAY);
        Mat result_img_processing = det1.processImage(frame, pointsA, pointsB, cropRegion);
        //cv::imshow("2", result_img_processing);

        cv::line(frame_data, pointsA[2], pointsA[1], Scalar(255, 0, 255), 2);
        cv::line(frame_data, pointsA[0], pointsA[3], Scalar(255, 0, 255), 2);

        cv::line(frame_data, pointsB[2] + cv::Point(pointsA[3].x, pointsA[0].y), pointsB[1] + cv::Point(pointsA[3].x, pointsA[0].y), Scalar(255, 0, 255), 2);
        cv::line(frame_data, pointsB[0] + cv::Point(pointsA[3].x, pointsA[0].y), pointsB[3] + cv::Point(pointsA[3].x, pointsA[0].y), Scalar(255, 0, 255), 2);

        //int segmentation = 65;
        cv::line(frame_data, cv::Point(pointsA[3].x + cam.D, pointsA[0].y), cv::Point(pointsA[3].x + cam.D, pointsA[0].y + 40), Scalar(255, 255, 255), 2);
        result_img = det1.detResult(result_img_processing,cam.D,cam.C);



        cv::cvtColor(frame, frame, cv::COLOR_GRAY2BGR);

        std::string result_text = (result_img ? "true" : "false");
        cv::Point text_position(30, 50);
        int font_face = cv::FONT_HERSHEY_SIMPLEX;
        double font_scale = 3;
        int thickness = 2;
        cv::Scalar text_color(0, 0, 255);

        // 将文本绘制到图像上
        cv::putText(frame_data, result_text, text_position, font_face, font_scale, text_color, thickness);

        for (const Point& pt : pointsA)
        {
            circle(frame, pt, 5, Scalar(0, 0, 255), -1);
            //string text = "(" + to_string(pt.x) + ", " + to_string(pt.y) + ")";
            //putText(frame_clone, text, pt - Point(10, 20), font_face, 1, text_color, thickness);
        }

        for (int i = 1; i < 4; ++i)
        {
            Point pt = pointsB[i];
            pt += cv::Point(pointsA[3].x, pointsA[0].y);

            // 绘制点
            circle(frame_data, pt, 5, Scalar(0, 255, 0), -1);

            // 添加坐标文本
            //string text = "(" + to_string(pt.x) + ", " + to_string(pt.y) + ")";
            //putText(frame_clone, text, pt + Point(10, 20), font_face, 1, Scalar(0, 255, 0), thickness);
        }

        circle(frame_data, (pointsB[0] + cv::Point(pointsA[3].x, pointsA[0].y)), 5, Scalar(0, 255, 0), -1);
        //string text = "(" + to_string(pointsB[0].x+ pointsA[3].x) + ", " + to_string(pointsB[0].y+ pointsA[0].y) + ")";
        //putText(frame_clone, text, pointsB[0] + Point(-80, 40)+ cv::Point(pointsA[3].x, pointsA[0].y), font_face, 1, Scalar(0, 255, 0), thickness);

        //resize(frame_clone, frame_clone, Size(frame.cols * 2, frame.rows * 2));
        // cv::imshow("Frame", frame_clone);
        // cv::waitKey(1);
        //if (cv::waitKey(1000 / fps) == 'q') {
        //    break;
        //}
        ////// 增加帧计数
        //frame_count++;

        /*}
        cap.release();
        cv::destroyAllWindows();*/
    }
    catch (const std::exception& ex) {
        std::cerr << "Error: " << ex.what() << std::endl;
        return -1;
    }
}

int C_Mid1_CV_det(cv::Mat& frame_data, const CamParam& cam, bool& result_img)
{
    ImageDet  det2;
    /*Mat img = imread("D:/img/cut/cold/1frame_68.jpg",0);
    waitKey(0);*/
    //VideoCapture cap("D:/img/cut/2_cold.mp4");  // 替换成你的视频文件路径

    //double fps = cap.get(CAP_PROP_FPS);
    //if (!cap.isOpened()) {
    //    cerr << "无法打开视频文件！" << endl;
    //    return -1;
    //}
    ////namedWindow("Video", WINDOW_NORMAL);

    ////cv::VideoCapture cap("D:/img/cut/2_cold.mp4");
    ////int total_frames = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_COUNT));
    ////double fps = cap.get(cv::CAP_PROP_FPS);
    //cv::Mat frame;
    //int frame_count = 0;



    //画一个大ROI
    std::vector<Point> pointsA = {
        Point(cam.A[0],cam.A[1]),
        Point(cam.A[2],cam.A[3]),
        Point(cam.A[4],cam.A[5]),
        Point(cam.A[6],cam.A[7])
    };

    //一个小ROI
    std::vector<Point> pointsB = {
        Point(cam.B[0],cam.B[1]),
        Point(cam.B[2],cam.B[3]),
        Point(cam.B[4],cam.B[5]),
        Point(cam.B[6],cam.B[7])
    };


    // 定义裁剪区域
    Rect cropRegion(pointsA[3].x, pointsA[0].y, pointsA[2].x - pointsA[3].x, pointsA[2].y - pointsA[1].y);

    try
    {
        // 逐帧读取视频
        /*  while (true)
        {*/
        // 读取一帧图像
        /*cap >> frame;*/


        /*  string filename = "test.jpg";
              imwrite(filename, frame); */

        /*std::string filename = "D:/image/image_" + getCurrentTimeString() + ".png";
            cv::imwrite(filename, frame);*/
        //cv::Mat frame(480, 640, CV_8UC3, (void*)imageData);
        //Mat frame_clone = frame.clone();
        Mat frame=frame_data.clone();
        cv::cvtColor(frame, frame, cv::COLOR_BGR2GRAY);
        Mat result_img_processing = det2.processImage(frame, pointsA, pointsB, cropRegion);
        //cv::imshow("2", result_img_processing);
        Mat gradY;
        Sobel(result_img_processing, gradY, CV_16S, 0, 1, 3);
        convertScaleAbs(gradY, gradY);

        cv::line(frame_data, pointsA[2], pointsA[1], Scalar(255, 0, 255), 2);
        cv::line(frame_data, pointsA[0], pointsA[3], Scalar(255, 0, 255), 2);

        cv::line(frame_data, pointsB[2] + cv::Point(pointsA[3].x, pointsA[0].y), pointsB[1] + cv::Point(pointsA[3].x, pointsA[0].y), Scalar(255, 0, 255), 2);
        cv::line(frame_data, pointsB[0] + cv::Point(pointsA[3].x, pointsA[0].y), pointsB[3] + cv::Point(pointsA[3].x, pointsA[0].y), Scalar(255, 0, 255), 2);

        //int segmentation = 65;
        cv::line(frame_data, cv::Point(pointsA[3].x + cam.D, pointsA[0].y), cv::Point(pointsA[3].x + cam.D, pointsA[0].y + 40), Scalar(255, 255, 255), 2);
        result_img = det2.detResult(gradY,cam.D,cam.C);



        cv::cvtColor(frame, frame, cv::COLOR_GRAY2BGR);

        std::string result_text = (result_img ? "true" : "false");
        cv::Point text_position(30, 50);
        int font_face = cv::FONT_HERSHEY_SIMPLEX;
        double font_scale = 3;
        int thickness = 2;
        cv::Scalar text_color(0, 0, 255);

        // 将文本绘制到图像上
        cv::putText(frame_data, result_text, text_position, font_face, font_scale, text_color, thickness);

        for (const Point& pt : pointsA)
        {
            circle(frame, pt, 5, Scalar(0, 0, 255), -1);
            //string text = "(" + to_string(pt.x) + ", " + to_string(pt.y) + ")";
            //putText(frame_clone, text, pt - Point(10, 20), font_face, 1, text_color, thickness);
        }

        for (int i = 1; i < 4; ++i)
        {
            Point pt = pointsB[i];
            pt += cv::Point(pointsA[3].x, pointsA[0].y);

            // 绘制点
            circle(frame_data, pt, 5, Scalar(0, 255, 0), -1);

            // 添加坐标文本
            //string text = "(" + to_string(pt.x) + ", " + to_string(pt.y) + ")";
            //putText(frame_clone, text, pt + Point(10, 20), font_face, 1, Scalar(0, 255, 0), thickness);
        }

        circle(frame_data, (pointsB[0] + cv::Point(pointsA[3].x, pointsA[0].y)), 5, Scalar(0, 255, 0), -1);
        //string text = "(" + to_string(pointsB[0].x+ pointsA[3].x) + ", " + to_string(pointsB[0].y+ pointsA[0].y) + ")";
        //putText(frame_clone, text, pointsB[0] + Point(-80, 40)+ cv::Point(pointsA[3].x, pointsA[0].y), font_face, 1, Scalar(0, 255, 0), thickness);

        //resize(frame_clone, frame_clone, Size(frame.cols * 2, frame.rows * 2));
        // cv::imshow("Frame", frame_clone);
        // cv::waitKey(1);
        //if (cv::waitKey(1000 / fps) == 'q') {
        //    break;
        //}
        ////// 增加帧计数
        //frame_count++;

        /*}
        cap.release();
        cv::destroyAllWindows();*/
    }
    catch (const std::exception& ex) {
        std::cerr << "Error: " << ex.what() << std::endl;
        return -1;
    }
}
